package com.mini.grpc.client;

import com.mini.grpc.common.Metadata;
import com.mini.grpc.common.Status;

/**
 * ClientCall表示一个RPC调用，提供了发送请求和接收响应的方法。
 *
 * @param <ReqT> 请求类型
 * @param <RespT> 响应类型
 */
public interface ClientCall<ReqT, RespT> {
    
    /**
     * 开始一个调用
     *
     * @param responseListener 响应监听器
     * @param headers 请求头
     */
    void start(Listener<RespT> responseListener, Metadata headers);
    
    /**
     * 请求接收指定数量的消息
     *
     * @param numMessages 请求的消息数量
     */
    void request(int numMessages);
    
    /**
     * 发送消息
     *
     * @param message 要发送的消息
     */
    void sendMessage(ReqT message);
    
    /**
     * 结束调用，表示客户端不再发送消息
     */
    void halfClose();
    
    /**
     * 取消调用
     *
     * @param message 取消原因
     * @param cause 取消异常
     */
    void cancel(String message, Throwable cause);
    
    /**
     * 判断调用是否已取消
     *
     * @return 如果调用已取消则返回true，否则返回false
     */
    boolean isCancelled();
    
    /**
     * 响应监听器，用于接收来自服务端的响应和事件
     *
     * @param <RespT> 响应类型
     */
    abstract class Listener<RespT> {
        
        /**
         * 当收到头部元数据时调用
         *
         * @param headers 头部元数据
         */
        public void onHeaders(Metadata headers) {}
        
        /**
         * 当收到消息时调用
         *
         * @param message 收到的消息
         */
        public abstract void onMessage(RespT message);
        
        /**
         * 当调用关闭时调用
         *
         * @param status 关闭状态
         * @param trailers 尾部元数据
         */
        public abstract void onClose(Status status, Metadata trailers);
        
        /**
         * 当调用准备好接收更多消息时调用
         */
        public void onReady() {}
    }
} 